﻿using System;
using System.Linq;
using System.Linq.Expressions;
using Zero.Data;
using Zero.Data.Infrastructure;


namespace Zero.Service
{
    public abstract  class GenericServiceBase<T>  where T : BaseEntity
    {
        public IUnitOfWork unitOfWork { get; set; }
        public  IRepository<T> CurrentRepository { get; set; }
        public GenericServiceBase(IRepository<T> CurrentRepository,IUnitOfWork unitOfWork)
        {
            this.CurrentRepository = CurrentRepository;
            this.unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 获取实体
        /// </summary>
        /// <param name="id">主键</param>
        /// <returns></returns>
        public virtual T Get(object id)
        {
            if (id == null)
                return null;
            return this.CurrentRepository.Get(id);
        }

        /// <summary>
        /// 获取所有实体
        /// </summary>
        /// <returns></returns>
        public virtual IQueryable<T> GetAll()
        {
            return this.CurrentRepository.GetAll().OrderBy(m=>m.OrderIndex).AsQueryable();
        }

        /// <summary>
        /// 获取满足条件的实体集合
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual IQueryable<T> GetMany(Expression<Func<T, bool>> where)
        {
            return this.CurrentRepository.GetMany(where).OrderBy(m=>m.OrderIndex).AsQueryable();
        }


        /// <summary>
        /// 根据键值获取指定实体
        /// </summary>
        /// <param name="keys"></param>
        /// <returns></returns>
        public virtual T Find(params object[] keys)
        {
            return this.CurrentRepository.Find(keys);
        }

        /// <summary>
        /// 根据表达式条件获取实体
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual T Find(Expression<Func<T, bool>> predicate)
        {
            return this.CurrentRepository.Find(predicate);
        }

        /// <summary>
        /// 分页获取指定实体集合
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="total"></param>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public virtual IQueryable<T> GetByPage(Expression<Func<T, bool>> filter, out int total, int page, int size)
        {
            return this.CurrentRepository.GetByPage(filter, out total, page, size).OrderBy(m => m.OrderIndex);
        }

        /// <summary>
        /// 添加实体
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Add(T entity)
        {
            entity.IsDel = false;
            this.CurrentRepository.Add(entity);
            unitOfWork.Commit();
        }

        /// <summary>
        /// 更新实体
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Update(T entity)
        {
            this.CurrentRepository.Update(entity);
            this.unitOfWork.Commit();
        }

        /// <summary>
        /// 物理删除实体
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Remove(T entity)
        {
            this.CurrentRepository.Remove(entity);
            unitOfWork.Commit();
        }

        /// <summary>
        /// 根据物理删除实体
        /// </summary>
        /// <param name="id">主键</param>
        public virtual void Remove(object id)
        {
            this.CurrentRepository.Remove(id);
            this.unitOfWork.Commit();
        }

        /// <summary>
        /// 逻辑删除实体
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Delete(T entity)
        {
            this.CurrentRepository.Delete(entity);
            this.unitOfWork.Commit();
        }


        /// <summary>
        /// 根据主键逻辑删除实体
        /// </summary>
        /// <param name="id"></param>
        public virtual void Delete(object id)
        {
            this.CurrentRepository.Delete(id);
            this.unitOfWork.Commit();
        }

        /// <summary>
        /// 逻辑删除满足条件的实体集合
        /// </summary>
        /// <param name="where"></param>
        public virtual void Delete(Expression<Func<T, bool>> where)
        {
            this.CurrentRepository.Delete(where);
            this.unitOfWork.Commit();
        }

        public virtual int Count
        {
            get { return this.CurrentRepository.Count; }
        }
    }

    #region 接口
    //public interface IGenericManager<T> where T : class
    //{

    //    /// <summary>
    //    /// 获取实体
    //    /// </summary>
    //    /// <param name="id">主键</param>
    //    /// <returns></returns>
    //    T Get(object id);

    //    /// <summary>
    //    /// 获取所有实体
    //    /// </summary>
    //    /// <returns></returns>
    //    IQueryable<T> GetAll();


    //    /// <summary>
    //    /// 获取满足条件的实体集合
    //    /// </summary>
    //    /// <param name="where"></param>
    //    /// <returns></returns>
    //    IQueryable<T> GetMany(Expression<Func<T, bool>> where);

    //    /// <summary>
    //    /// 根据键值获取指定实体
    //    /// </summary>
    //    /// <param name="keys"></param>
    //    /// <returns></returns>
    //    T Find(params object[] keys);

    //    /// <summary>
    //    /// 根据表达式条件获取实体
    //    /// </summary>
    //    /// <param name="predicate"></param>
    //    /// <returns></returns>
    //    T Find(Expression<Func<T, bool>> predicate);

    //    /// <summary>
    //    /// 分页获取指定实体集合
    //    /// </summary>
    //    /// <param name="filter"></param>
    //    /// <param name="total"></param>
    //    /// <param name="page"></param>
    //    /// <param name="size"></param>
    //    /// <returns></returns>
    //    IQueryable<T> GetByPage(Expression<Func<T, bool>> filter, out int total, int page, int size);


    //    /// <summary>
    //    /// 添加实体
    //    /// </summary>
    //    /// <param name="entity"></param>
    //   void Add(T entity);

    //    /// <summary>
    //    /// 更新实体
    //    /// </summary>
    //    /// <param name="entity"></param>
    //    void Update(T entity);

    //    /// <summary>
    //    /// 物理删除实体
    //    /// </summary>
    //    /// <param name="entity"></param>
    //    void Remove(T entity);

    //    /// <summary>
    //    /// 根据物理删除实体
    //    /// </summary>
    //    /// <param name="id">主键</param>
    //    void Remove(object id);

    //    /// <summary>
    //    /// 逻辑删除实体
    //    /// </summary>
    //    /// <param name="entity"></param>
    //    void Delete(T entity);

    //    /// <summary>
    //    /// 根据主键逻辑删除实体
    //    /// </summary>
    //    /// <param name="id"></param>
    //    void Delete(object id);

    //    /// <summary>
    //    /// 逻辑删除满足条件的实体集合
    //    /// </summary>
    //    /// <param name="where"></param>
    //    void Delete(Expression<Func<T, bool>> where);

    //} 
    #endregion
}
